package com.wstuo.itsm.cim.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.dictionary.dao.IDataDictionaryItemsDAO;
import com.wstuo.common.config.dictionary.entity.DataDictionaryItems;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;
import com.wstuo.itsm.cim.dao.IBehaviorModificationDAO;
import com.wstuo.itsm.cim.dao.ICIDAO;
import com.wstuo.itsm.cim.dao.ICIRelevanceDAO;
import com.wstuo.itsm.cim.dto.CIRelevanceDTO;
import com.wstuo.itsm.cim.dto.CiRelevanceTreeViewDTO;
import com.wstuo.itsm.cim.entity.CI;
import com.wstuo.itsm.cim.entity.BehaviorModification;
import com.wstuo.itsm.cim.entity.CIRelevance;

/**
 * 关联配置项Service类
 * 
 * @author QXY
 * 
 */
public class CIRelevanceService implements ICIRelevanceService {
	@Autowired
	private ICIRelevanceDAO ciRelevanceDAO;
	@Autowired
	private ICIDAO ciDAO;
	@Autowired
	private IDataDictionaryItemsDAO dataDictionaryItemsDAO;
	@Autowired
	private IBehaviorModificationDAO behaviorModificationDAO;
	@Autowired
	private AppContext appctx;

	/**
	 * 关联配置项实体转DTO
	 * 
	 * @param ciEntity
	 *            :要转到DTO的实体
	 * @param ciDto
	 *            ：存放实体的DTO return void
	 */
	private void entity2dto(CIRelevance ciEntity, CIRelevanceDTO ciDto) {
		try {
			ciDto.setRelevanceId(ciEntity.getRelevanceId());
			ciDto.setRelevanceDesc(ciEntity.getRelevanceDesc());
			ciDto.setCiRelevanceName(ciEntity.getCiRelevanceId().getCiname());
			ciDto.setCiRelevanceId(ciEntity.getCiRelevanceId().getCiId());
			ciDto.setUnCiRelevanceId(ciEntity.getUnCiRelevanceId().getCiId());
			ciDto.setUnCiRelevanceName(ciEntity.getUnCiRelevanceId()
					.getCiname());
			if (ciEntity.getCiRelationType() != null) {// 关系类型
				ciDto.setCiRelationTypeNo(ciEntity.getCiRelationType()
						.getDcode());
				ciDto.setCiRelationTypeName(ciEntity.getCiRelationType()
						.getDname());
				ciDto.setCiRelationTypeNameColor(ciEntity.getCiRelationType()
						.getColor());// 配置项CI的关系类型背景色
			}
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * 
	 * 关联配置项分页查询方法
	 * 
	 * @return PageDTO
	 */
	@SuppressWarnings("unchecked")
	public PageDTO configureItemRelevanceFindPager(Long ciRelevanceId,
			int start, int limit, String sord, String sidx) {
		PageDTO page = ciRelevanceDAO.findPager(ciRelevanceId, start, limit,
				sord, sidx);

		List<CIRelevance> entities = (List<CIRelevance>) page.getData();
		List<CIRelevanceDTO> dtos = new ArrayList<CIRelevanceDTO>(
				entities.size());

		for (CIRelevance entity : entities) {
			CIRelevanceDTO dto = new CIRelevanceDTO();
			entity2dto(entity, dto);
			dtos.add(dto);
		}

		page.setData(dtos);

		return page;
	};

	/**
	 * 关联配置项添加
	 */
	@Transactional
	public void configureItemRelevanceAdd(CIRelevanceDTO ciRelevanceDTO) {
		LanguageContent lc = LanguageContent.getInstance();
		String msg="";
		CIRelevance ciRelevance = new CIRelevance();
		ciRelevance.setRelevanceDesc(ciRelevanceDTO.getRelevanceDesc());
		CI ci = new CI();
		if (ciRelevanceDTO.getCiRelevanceId() != null) {
			ci = ciDAO.findById(ciRelevanceDTO.getCiRelevanceId());
			ciRelevance.setCiRelevanceId(ci);
		}
		if (ciRelevanceDTO.getUnCiRelevanceId() != null) {
			msg+=lc.getContent("lable.New.configuration")+"【"+ciRelevanceDTO.getUnCiRelevanceName()+"("+ciRelevanceDTO.getUnCiRelevanceId()+")】<br/>";
			ci = ciDAO.findById(ciRelevanceDTO.getUnCiRelevanceId());
			ciRelevance.setUnCiRelevanceId(ci);
		}
		if (ciRelevanceDTO.getCiRelationTypeNo() != null) {// 关系类型
			DataDictionaryItems ciRelationType= dataDictionaryItemsDAO.findById(ciRelevanceDTO.getCiRelationTypeNo());
			msg+=lc.getContent("label.dc.ciRelationType")+"【"+ciRelationType.getDname()+"】<br/>";
			ciRelevance.setCiRelationType(ciRelationType);
		}
		msg+=lc.getContent("common.remark")+"【"+ciRelevanceDTO.getRelevanceDesc()+"】";
		ciRelevanceDAO.save(ciRelevance);
		ciRelevanceDTO.setRelevanceId(ciRelevance.getRelevanceId());
		
		//修改行为
		BehaviorModification behaviormodification=new BehaviorModification();
		behaviormodification.setActContent(msg);
		behaviormodification.setCiId(ciRelevanceDTO.getCiRelevanceId());
		String userName = appctx.getCurrentLoginName();
		behaviormodification.setUserName(userName);
		behaviorModificationDAO.save(behaviormodification);
	}

	/**
	 * 关联配置项更新
	 */
	@Transactional
	public void configureItemRelevanceUpdate(CIRelevanceDTO ciRelevanceDTO) {
		CIRelevance ciRelevance = ciRelevanceDAO.findById(ciRelevanceDTO.getRelevanceId());
		String msg="";
		

		CI ci = new CI();
		if (ciRelevanceDTO.getCiRelevanceId() != null) {
			ci = ciDAO.findById(ciRelevanceDTO.getCiRelevanceId());
			ciRelevance.setCiRelevanceId(ci);
		}
		if (ciRelevanceDTO.getUnCiRelevanceId() != null) {
			ci = ciDAO.findById(ciRelevanceDTO.getUnCiRelevanceId());
			msg+=comparativeData("label.request.withAssets",ciRelevance.getUnCiRelevanceId().getCiname()+"("+ciRelevance.getUnCiRelevanceId().getCiId()+")", ci.getCiname()+"("+ciRelevanceDTO.getUnCiRelevanceId()+")");
			ciRelevance.setUnCiRelevanceId(ci);
		}
		String type="";
		String oldtype="";
		if(ciRelevance.getCiRelationType()!=null){
			type=ciRelevance.getCiRelationType().getDname();
		}
		if (ciRelevanceDTO.getCiRelationTypeNo() != null) {// 关系类型
			DataDictionaryItems ciRelationType= dataDictionaryItemsDAO.findById(ciRelevanceDTO.getCiRelationTypeNo());
			oldtype=ciRelationType.getDname();
			ciRelevance.setCiRelationType(ciRelationType);
		} else {
			ciRelevance.setCiRelationType(null);
		}
		msg+=comparativeData("label.dc.ciRelationType",type,oldtype);
		
		msg+=comparativeData("common.remark", ciRelevance.getRelevanceDesc(), ciRelevanceDTO.getRelevanceDesc());
		ciRelevance.setRelevanceDesc(ciRelevanceDTO.getRelevanceDesc());
		
		ciRelevanceDAO.merge(ciRelevance);
		
		//保存修改行为
		if(msg!=null && msg!="" && msg.length()>0){
			BehaviorModification behaviormodification=new BehaviorModification();
			behaviormodification.setActContent(msg.replaceAll("【null】","【】"));
			behaviormodification.setCiId(ciRelevanceDTO.getCiRelevanceId());
			String userName = appctx.getCurrentLoginName();
			behaviormodification.setUserName(userName);
			behaviorModificationDAO.save(behaviormodification);
		}
	}
	/**
	 * 数据的前后对比
	 * */
	@Transactional
	public String comparativeData(String key,String oldval,String val){
		String result="";
		LanguageContent lc = LanguageContent.getInstance();
		if(StringUtils.hasText(val) && StringUtils.hasText(oldval) && !val.equals(oldval)){
			result=lc.getContent(key)+"："+lc.getContent("lable.By.the")+"【"+oldval+"】"+lc.getContent("lable.Revised.to")+"【"+val+"】<br/>";
		}else if(!StringUtils.hasText(val) && StringUtils.hasText(oldval)){
			result=lc.getContent(key)+"："+lc.getContent("lable.By.the")+"【"+oldval+"】"+lc.getContent("lable.Revised.to")+"【】<br/>";
		}else if(!StringUtils.hasText(oldval) && StringUtils.hasText(val)){
			result=lc.getContent(key)+"："+lc.getContent("lable.By.the")+"【】"+lc.getContent("lable.Revised.to")+"【"+val+"】<br/>";
		}
		return result;
	}
	/**
	 * 关联配置项批量删除
	 */
	@Transactional
	public void configureItemRelevanceDelete(Long[] relevanceIds) {
		if (relevanceIds != null) {
			List<CIRelevance> reList = new ArrayList<CIRelevance>();
			for (Long id : relevanceIds) {
				CIRelevance cirele = ciRelevanceDAO.findById(id);
				reList.add(cirele);
				
				//修改行为
				LanguageContent lc = LanguageContent.getInstance();
				BehaviorModification behaviormodification=new BehaviorModification();
				behaviormodification.setActContent(lc.getContent("label.request.withAssets")+"【"+cirele.getUnCiRelevanceId().getCiname()+"("+cirele.getUnCiRelevanceId().getCiId()+")】"+lc.getContent("common.delete"));
				behaviormodification.setCiId(cirele.getCiRelevanceId().getCiId());
				String userName = appctx.getCurrentLoginName();
				behaviormodification.setUserName(userName);
				behaviorModificationDAO.save(behaviormodification);
			}
			ciRelevanceDAO.deleteAll(reList);
		}

	}

	private static void entity2dto1(CIRelevance entity, CIRelevanceDTO dto) {
		try {
			dto.setCiRelevanceId(entity.getRelevanceId());
			dto.setCiRelevanceId(entity.getCiRelevanceId().getCiId());
			dto.setCiRelevanceName(entity.getCiRelevanceId().getCiname());
			dto.setRelevanceDesc(entity.getRelevanceDesc());
			dto.setUnCiRelevanceId(entity.getUnCiRelevanceId().getCiId());
			dto.setUnCiRelevanceName(entity.getUnCiRelevanceId().getCiname());
		} catch (Exception ex) {
			throw new ApplicationException(ex);
		}

	}

	private void entity2dto(CIRelevance entity, CiRelevanceTreeViewDTO dto) {

		CIRelevanceDTO ciReleDto = new CIRelevanceDTO();
		entity2dto1(entity, ciReleDto);

		dto.setData(ciReleDto.getCiRelevanceName());

		dto.getAttr().put("relevanceId", "" + ciReleDto.getRelevanceId());
		dto.getAttr().put("relevanceDesc", ciReleDto.getRelevanceDesc());
		dto.getAttr().put("ciRelevanceId", "" + ciReleDto.getCiRelevanceId());
		dto.getAttr().put("ciRelevanceName", ciReleDto.getCiRelevanceName());
		dto.getAttr().put("unCiRelevanceId",
				"" + ciReleDto.getUnCiRelevanceName());
		dto.getAttr()
				.put("unCiRelevanceName", ciReleDto.getUnCiRelevanceName());

	}

	private void entity2dto2(CIRelevance entity, CiRelevanceTreeViewDTO dto) {

		CIRelevanceDTO ciReleDto = new CIRelevanceDTO();
		entity2dto1(entity, ciReleDto);

		dto.setData(ciReleDto.getUnCiRelevanceName());
		dto.getAttr().put("relevanceId", "" + ciReleDto.getRelevanceId());
		dto.getAttr().put("relevanceDesc", ciReleDto.getRelevanceDesc());

		dto.getAttr().put("ciRelevanceId", "" + ciReleDto.getUnCiRelevanceId());
		dto.getAttr().put("ciRelevanceName", ciReleDto.getUnCiRelevanceName());

		dto.getAttr().put("unCiRelevanceId", "" + ciReleDto.getCiRelevanceId());
		dto.getAttr().put("unCiRelevanceName", ciReleDto.getCiRelevanceName());

	}

	/**
	 * 关联配置项树
	 * 
	 * @param ciId
	 * @return List<CiRelevanceTreeViewDTO>
	 */
	@Transactional
	public CiRelevanceTreeViewDTO ciReleTree(Long ciId, String forward,
			String back) {
		// 关联配置项
		List<CIRelevance> ciReleList = ciRelevanceDAO.findCiRelevanceList(ciId);
		// 被关联配置项
		List<CIRelevance> nuCiReleList = ciRelevanceDAO
				.findNuCiRelevanceList(ciId);
		
		
		// 返回树
		CiRelevanceTreeViewDTO dto = new CiRelevanceTreeViewDTO();
		CI ci = ciDAO.findById(ciId);
		dto.setData(ci.getCiname());
		dto.getAttr().put("ciRelevanceId", String.valueOf(ci.getCiId()));
		dto.getAttr().put("ciRelevanceName", ci.getCiname());

		// 子点：关联
		CiRelevanceTreeViewDTO dto1 = new CiRelevanceTreeViewDTO();

		dto1.setData(forward);
		dto1.getAttr().put("ciRelevanceId", "");
		dto1.getAttr().put("ciRelevanceName", forward);

		List<CiRelevanceTreeViewDTO> ciReleTree1 = new ArrayList<CiRelevanceTreeViewDTO>();
		for (CIRelevance cire : ciReleList) {
			CiRelevanceTreeViewDTO cireledto = new CiRelevanceTreeViewDTO();
			entity2dto2(cire, cireledto);
			ciReleTree1.add(cireledto);
		}
		dto1.setChildren(ciReleTree1);

		// 子点：被关联
		CiRelevanceTreeViewDTO dto2 = new CiRelevanceTreeViewDTO();
		dto2.setData(back);
		dto2.getAttr().put("ciRelevanceId", "");
		dto2.getAttr().put("ciRelevanceName", back);
		List<CiRelevanceTreeViewDTO> ciReleTree2 = new ArrayList<CiRelevanceTreeViewDTO>();
		for (CIRelevance cire : nuCiReleList) {
			CiRelevanceTreeViewDTO cireledto = new CiRelevanceTreeViewDTO();
			entity2dto(cire, cireledto);
			ciReleTree2.add(cireledto);
		}
		dto2.setChildren(ciReleTree2);

		List<CiRelevanceTreeViewDTO> ciReleTree = new ArrayList<CiRelevanceTreeViewDTO>();
		ciReleTree.add(dto1);
		ciReleTree.add(dto2);

		dto.setChildren(ciReleTree);

		return dto;
	}

	/**
	 * 判断当前关联配置项是否已关联
	 * 
	 * @param ciReleDto
	 * @return boolean
	 */
	public boolean isCIRelevance(CIRelevanceDTO ciReleDto) {
		return ciRelevanceDAO.isCIRelevance(ciReleDto);
	}

	/**
	 * 根据ID获取关联配置项
	 * 
	 * @param id
	 * @return String
	 */
	public CIRelevanceDTO findCiRelevanceById(Long id) {
		CIRelevance ciRelevance = ciRelevanceDAO.findById(id);
		CIRelevanceDTO dto = new CIRelevanceDTO();
		entity2dto(ciRelevance, dto);
		return dto;
	}

}
